package cybercode.carsaleserver.controller;


import lombok.extern.log4j.Log4j2;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.HandlerMethod;
import org.wheat.infectionreport.dto.R;
import org.wheat.infectionreport.dto.ResultCode;

import javax.servlet.http.HttpServletRequest;

@Log4j2
@RestControllerAdvice
public class ControllerExceptionHandler {

    /**
     * 参数不匹配异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public R methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        FieldError err = e.getBindingResult().getFieldError();

        String errMsg;
        if (null != err) {
            errMsg = err.getDefaultMessage();
            log.debug("[{}]参数错误, {}", err.getField(), errMsg);
        } else {
            errMsg = e.getMessage();
            log.warn("[{}]参数错误", e.getBindingResult().getObjectName(), e);
        }

        return R.fail(ResultCode.PARAM_VALID_ERROR, "入参异常: " + errMsg);
        //getDefaultMessage()会返回message信息
    }


    // 捕捉其他所有异常
    @ExceptionHandler(Exception.class)
    public R globalException(HttpServletRequest request, HandlerMethod handlerMethod, Throwable ex) {

        log.error("[{}]发生错误, 主要信息: {}, 处理方法: {}",
                request.getRequestURI(), ex.getMessage(), handlerMethod.getMethod().getName(), ex);

        return R.fail(ResultCode.FAILURE, "服务器异常: " + getStatus(request).value() + ", " + ex.getMessage());

    }


    /**
     * 获取响应状态码
     *
     * @param request
     * @return
     */
    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        return HttpStatus.valueOf(statusCode);
    }
}
